package main

import (
	"fmt"
	"sync"
)

// 10. 请您写一段简单的示例代码来表示Go协程+Channel的用法

/*
首先Channel的作用是goroutine 和 goroutine 之间的双向通道，和函数一样都是一等公民，学习时，听说过这样一句话来自go语言作者：不要通过共享内存来进行通信，通过通信来共享内存。

下面举一个channel的例子，我印象比较深刻，在我的基础学习笔记中也有这个例子，是在一个go学习群中，一个群友问了一个问题：一个经典的生产者消费者的问题，他使用了一个channel，两个函数内是两个死循环。一个函数负责接收，一个函数负责发送，但是因为并发的情况下不能按照要求 send 0, receive 0; send 1, receive 1；... 这样的顺序执行，然后我使用 WaitGroup代替 for死循环，等待任务结束，然后通过一个 in chan接收，另一个 done chan，传递信息（通信）。实现上面的功能。
*/

func send(in chan int, done chan bool, wg *sync.WaitGroup) {
	for i := 0; i < 5; i++ {
		in <- i
		fmt.Println("send ", i)
		// 等待消费者，发送处理完的请求
		<- done
	}
	wg.Done()
}

func receive(in chan int, done chan bool, wg *sync.WaitGroup) {
	for i := 0; i < 5; i++ {
		num := <- in
		fmt.Println("receive ", num)
		// 向生产者发送接收成功的信号
		done <- true
	}
	wg.Done()
}

func main() {
	// 创建 channel
	in := make(chan int)
	done := make(chan bool)
	// 创建 wg *sync.WaitGroup
	var wg sync.WaitGroup
	// 添加两个任务
	wg.Add(2)
	// 启动
	go send(in, done, &wg)
	go receive(in, done, &wg)
	// 等待任务执行结束
	wg.Wait()
	fmt.Println("任务执行结束")
}
选择题有些没看清要求，没有按照 fmt.Printf() 中的格式去输出。
第二题是：make创建的slice， 初始化空间为 1， cap是10。值传递，函数内并不改变原arr。答案是 0,1,3
第三题：编译报错（我写成了编译错误）
第四题：结构体实现的方法，其实就是一种语法糖，因为 p是值传递，所以不改变结果，从前面得NewPeople，到后面其实都没赋值上。
第五题：同样是值传递，panic程序执行结束，不往下执行了。defer保持先进后出的特性。所以答案是 errorJohn
第六题：go中的 switch不需要加break.
第七题：unicode编码，中文字符占3字节。



